Groovy-Style Builder

Groovy, Kotlin 등과 같은 프로그래밍 언어는 도메인에 특화된 언어(Domain Specific Language, DSL)의
생성을 지원한다.
C++에서는 초기화 리스트 기능을 이용해서 DSL을 생성할 수 있다.
struct Tag{
std::string name;
std::string text;
std::vector<Tag> children;
std::vector<std::pair<std::string, std::string>> attributes;
friend std::ostream& operator<<(std::ostream& os, const Tag& tag){
// ...
}
};
위의 Tag 구조체는 이름과 텍스트, 자식 태그(내부 태그) 또는 HTML 속성을 저장할 수 있는 태그이다.
operator<<는 포매팅해서 출력하는 기능
- 태그가 이름과 텍스트로 초기화되는 경우
- 태그가 이름과 자식의 집합으로 초기화 되는 경우
struct Tag{
// ...
protected:
Tag(const std::string& name, const std::string& text): name(name), text(text) {}
Tag(const std::string& name, const std::vector<Tag>& children): name(name), children(children) {}
};
// Tag (P, IMG)
struct P: Tag{
explicit P(const std::string& text): Tag{"p", text} {}
P(std::initializer_list<Tag> children): Tag("p", children) {}
};
struct IMG: Tag{
explicit IMG(const std::string& url): Tag{"img", ""} {
attributes.emplace_back({"src", url});
}
};
//
std::cout<<
P{
IMG{"http://pokemon.com/pikachu.png"}
}
<<std::endl;
위처럼 add_child 메서드를 호출하지 않고도, DSL은 다른 태그들로 확장할 수 있다.
(초기화 리스트를 이용해서 객체를 확장)